<template>
  <!-- 搜索条件 -->
  <el-card class="top">
    <el-form class="search-form">
      <!-- 用户名 -->
      <el-form-item label="用户名：" prop="name">
        <el-input
            v-model="searchDataForm.name"
            clearable
            :prefix-icon="Avatar"
            placeholder="请你输入搜索用户名"
        />
      </el-form-item>
      <!-- 昵称 -->
      <el-form-item label="昵称：" prop="nickName">
        <el-input
            v-model="searchDataForm.nickName"
            clearable
            :prefix-icon="UserFilled"
            placeholder="请你输入搜索昵称"
        />
      </el-form-item>
      <!-- 手机号 -->
      <el-form-item label="手机号：" prop="phone">
        <el-input
            v-model="searchDataForm.phone"
            clearable
            :prefix-icon="Iphone"
            placeholder="请你输入搜索手机号"
        />
      </el-form-item>
      <!-- 邮箱 -->
      <el-form-item label="邮箱：" prop="email">
        <el-input
            v-model="searchDataForm.email"
            clearable
            :prefix-icon="Message"
            placeholder="请你输入搜索邮箱"
        />
      </el-form-item>
      <!-- 按钮 -->
      <el-form-item>
        <el-button type="primary" @click="searchForm">
          搜索
        </el-button>
        <el-button @click="resetForm">
          重置
        </el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <!-- 展示数据 -->
  <el-card class="bottom">
    <!-- 按钮 -->
    <el-button type="primary" @click="addUser">添加</el-button>
    <el-popconfirm title="你确定要批量删除吗？" width="260px"
                   @confirm="deleteSelectUser"
    >
      <template #reference>
        <el-button type="danger" size="default"
                   :disabled="!selectIdArr.length"
        >
          批量删除
        </el-button>
      </template>
    </el-popconfirm>
    <!-- 表格展示用户信息 -->
    <el-table style="width: 100%" height="50vh"
              class="bottom-table"
              :header-cell-style="{'text-align':'center'}"
              :cell-style="{'text-align':'center'}"
              :data="records"
              border
              @selection-change="selectChange"
    >
      <!-- 展开 -->
      <el-table-column fixed="left" type="expand">
        <template #default="props">
          <el-card class="unfold-card">
            <div class="unfold">
              <!-- 头像 -->
              <div>
                <el-image style="width: 180px; height: 180px"
                          :src="props.row.avatar"
                />
              </div>
              <div>
                <p>姓名: {{ props.row.name }}</p>
                <p>性别：{{ props.row.sex }}</p>
                <p>年龄：{{ props.row.age }}</p>
                <p>昵称: {{ props.row.nickName }}</p>
                <p>手机号: {{ props.row.phone }}</p>
                <p>邮箱: {{ props.row.email }}</p>
                <p>生日：{{ props.row.birthday }}</p>
              </div>
              <!-- 其他信息 -->
              <div>
                <p>地址: {{ props.row.address }}</p>
                <p>用户角色:
                  {{
                    props.row.userRoleJoinRoleDtoList ? props.row.userRoleJoinRoleDtoList.map(item => item.roleName) : []
                  }}</p>
                <p>描述：{{ props.row.description }}</p>
                <p>创建时间: {{ props.row.createTime }}</p>
                <p>更新时间: {{ props.row.updateTime }}</p>
                <p>创建者: {{ props.row.createUser }}</p>
                <p>更新者: {{ props.row.updateUser }}</p>
              </div>
            </div>
          </el-card>
        </template>
      </el-table-column>
      <!-- 多选框 -->
      <el-table-column fixed="left" type="selection" width="50"/>
      <!-- 序号 -->
      <el-table-column fixed="left" type="index" label="#" width="50"/>
      <!-- 头像 -->
      <el-table-column label="头像" width="60">
        <template #default="props">
          <div style="display: flex; justify-content: center; align-items: center">
            <el-image style="width: 24px; height: 24px" :src="props.row.avatar"/>
          </div>
        </template>
      </el-table-column>
      <!-- 姓名 -->
      <el-table-column sortable
                       prop="name"
                       label="姓名"
                       width="180"
                       show-overflow-tooltip
      />
      <!-- 昵称 -->
      <el-table-column sortable
                       prop="nickName"
                       label="昵称"
                       width="180"
                       show-overflow-tooltip
      />
      <!-- 手机号 -->
      <el-table-column sortable
                       prop="phone"
                       label="手机号"
                       width="180"
                       show-overflow-tooltip
      />
      <!-- 邮箱 -->
      <el-table-column sortable
                       prop="email"
                       label="邮箱"
                       show-overflow-tooltip
                       width="180"
      />
      <!-- 用户角色 -->
      <el-table-column label="用户角色"
                       prop="userRoleJoinRoleDtoList"
                       show-overflow-tooltip
                       width="200"
      >
        <template #default="props">
          <el-tag v-for="(item, index) in props.row.userRoleList"
                  :key="index"
                  style="margin-right: 5px"
          >
            {{ item.roleName }}
          </el-tag>
        </template>
      </el-table-column>
      <!-- 创建时间 -->
      <el-table-column sortable
                       prop="createTime"
                       label="创建时间"
                       show-overflow-tooltip
                       width="180"
      />
      <!-- 更新时间 -->
      <el-table-column sortable
                       prop="updateTime"
                       label="更新时间"
                       show-overflow-tooltip
                       width="180"
      />
      <!-- 创建者 -->
      <el-table-column sortable
                       prop="createUser"
                       label="创建者"
                       show-overflow-tooltip
                       width="180"
      />
      <!-- 更新者 -->
      <el-table-column sortable
                       prop="updateUser"
                       label="更新者"
                       show-overflow-tooltip
                       width="180"
      />
      <!-- 操作 -->
      <el-table-column fixed="right" label="操作" width="280">
        <template #default="props">
          <el-button type="primary"
                     icon="User"
                     size="small"
                     @click="setRole(props.row)"
          >
            分配角色
          </el-button>
          <el-button type="primary"
                     icon="Edit"
                     size="small"
                     @click="updateUser(props.row)"
          >
            编辑
          </el-button>
          <el-popconfirm :title="`你确定要删除${props.row.name}?`" width="260px"
                         @confirm="deleteUser(props.row.id)"
          >
            <template #reference>
              <el-button type="danger"
                         size="small"
                         icon="Delete"
              >
                删除
              </el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页器 -->
    <el-pagination v-model:current-page="pageNum"
                   v-model:page-size="pageSize"
                   :page-sizes="[5, 10, 15, 20]"
                   :background="true"
                   layout="prev, pager, next, jumper,->,sizes,total"
                   :total="totalRow"
                   @current-change="searchForm"
                   @size-change="searchForm"
    />
  </el-card>

  <!-- 抽屉结构:完成添加新的用户账号|更新已有的账号信息 -->
  <el-dialog v-model="drawer">
    <!-- 头部标题:将来文字内容应该动态的 -->
    <template #header>
      <h4>{{ userParams.id ? '更新用户' : '添加用户' }}</h4>
    </template>
    <!-- 身体部分 -->
    <template #default>
      <el-form :model="userParams"
               :rules="rules"
               ref="ruleFormRef"
               :inline="true"
               label-position="top"
               class="dialog-add-or-update-form"
      >
        <!-- 用户账号 -->
        <el-form-item label="用户账号" prop="username" v-if="!userParams.id">
          <el-input placeholder="请您输入用户账号"
                    v-model="userParams.username"
                    maxlength="20"
                    show-word-limit
                    clearable
          />
        </el-form-item>
        <!-- 用户密码 -->
        <el-form-item label="用户密码" prop="password" v-if="!userParams.id">
          <el-input placeholder="请您输入用户密码"
                    v-model="userParams.password"
                    maxlength="20"
                    show-word-limit
                    clearable
          />
        </el-form-item>
        <!-- 用户姓名 -->
        <el-form-item label="用户姓名" prop="name">
          <el-input placeholder="请您输入用户姓名"
                    v-model="userParams.name"
                    maxlength="20"
                    show-word-limit
                    clearable
          />
        </el-form-item>
        <!-- 用户昵称 -->
        <el-form-item label="用户昵称" prop="nickName">
          <el-input placeholder="请您输入用户昵称"
                    v-model="userParams.nickName"
                    maxlength="20"
                    show-word-limit
                    clearable
          />
        </el-form-item>
        <!-- 用户性别 -->
        <el-form-item label="性别" prop="sex">
          <el-radio-group v-model="userParams.sex">
            <el-radio label="1">男</el-radio>
            <el-radio label="2">女</el-radio>
            <el-radio label="3">未知</el-radio>
          </el-radio-group>
        </el-form-item>
        <!-- 用户年龄 -->
        <el-form-item label="年龄" prop="age">
          <el-input-number placeholder="请您输入年龄"
                           v-model="userParams.age"
                           :min="1"
                           :max="300"
                           controls-position="right"
          />
        </el-form-item>
        <!-- 用户邮箱 -->
        <el-form-item label="邮箱" prop="email">
          <el-input placeholder="请您输入用户邮箱"
                    v-model="userParams.email"
                    maxlength="50"
                    show-word-limit
                    clearable
          />
        </el-form-item>
        <!-- 用户手机号 -->
        <el-form-item label="手机号" prop="phone">
          <el-input placeholder="请您输入用户手机号"
                    v-model="userParams.phone"
                    maxlength="20"
                    show-word-limit
                    clearable
          />
        </el-form-item>
        <!-- 用户生日 -->
        <el-form-item label="生日" prop="birthday">
          <el-date-picker v-model="userParams.birthday"
                          type="datetime"
                          placeholder="选择日期"
                          clearable
                          style="width: 100%"
          />
        </el-form-item>
        <!-- 用户地址 -->
        <el-form-item label="地址" prop="address">
          <el-input placeholder="请您输入用户地址"
                    v-model="userParams.address"
                    maxlength="50"
                    show-word-limit
                    clearable
          />
        </el-form-item>
        <!-- 用户描述 -->
        <el-form-item label="描述" prop="description">
          <el-input type="textarea"
                    placeholder="请您输入用户描述"
                    v-model="userParams.description"
                    maxlength="50"
                    show-word-limit
                    clearable
          />
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button type="primary" @click="save(ruleFormRef)">确定</el-button>
        <el-button @click="cancel">取消</el-button>
      </div>
    </template>
  </el-dialog>
  <!--   抽屉结构:用户某一个已有的账号进行职位分配-->
  <el-drawer v-model="drawer1">
    <template #header>
      <h4>分配角色(职位)</h4>
    </template>
    <template #default>
      <el-form>
        <el-form-item label="用户姓名">
          <el-input v-model="userParams.name" :disabled="true"></el-input>
        </el-form-item>
        <el-form-item label="职位列表">
          <el-checkbox @change="handleCheckAllChange"
                       v-model="checkAll"
                       :indeterminate="isIndeterminate"
                       style="margin-right: 2vw"
          >
            全选
          </el-checkbox>
          <!-- 显示职位的的复选框 -->
          <el-checkbox-group v-model="userRole" @change="handleCheckedCitiesChange">
            <el-checkbox v-for="role in allRole" :key="role.roleCode" :label="role">
              {{ role.roleName }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button type="primary" @click="confirmClick">确定</el-button>
        <el-button @click="drawer1 = false">取消</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import {Avatar, Iphone, Message, UserFilled} from "@element-plus/icons-vue";
import {nextTick, onMounted, reactive, ref} from "vue";
import {
  adminAddUserBaseInfo,
  adminUpdateUserBaseInfo,
  deleteById,
  deleteByIds,
  Page,
  page,
  Records, searchByCondition
} from "@/api/user/user.ts";
import {ApiResponse} from "@/utils/request.ts";
import {FormInstance, FormRules, UploadProps} from "element-plus";
import {assignRoles, setRoles} from "@/api/user/user-role.ts";

interface SearchData {
  name: string
  nickName: string
  phone: string
  email: string
}

//代表一个职位的ts类型
export interface RoleData {
  id?: string | number
  roleName: string
  roleCode: string
  roleDesc: string
  roleId?: string | number
}


type AllRole = RoleData[];

// 搜索条件
const searchDataForm = reactive<SearchData>({
  name: '',
  nickName: '',
  phone: '',
  email: ''
})

const resetForm = () => {
  searchDataForm.name = ''
  searchDataForm.nickName = ''
  searchDataForm.phone = ''
  searchDataForm.email = ''
}

// 默认页码
const pageNum = ref<number>(1);
// 默认每页条数
const pageSize = ref<number>(10);
// 总条数
const totalRow = ref<number>(0);
// 存储表格数据
const records = ref<Records[]>([]);
// 页面加载完成存储头像
const avatar = ref<string[]>(['']);
// 定义响应式数据控制抽屉的显示与隐藏
const drawer = ref<boolean>(false);
//控制分配角色抽屉显示与隐藏
let drawer1 = ref<boolean>(false);
//存储全部职位的数据
let allRole = ref<AllRole>([]);
//当前用户已有的职位
let userRole = ref<AllRole>([]);
//收集顶部复选框全选数据
const checkAll = ref<boolean>(false);
//控制顶部全选复选框不确定的样式
const isIndeterminate = ref<boolean>(true);
// 校验表单的ref
const ruleFormRef = ref<FormInstance>()
//准备一个数组存储批量删除的用户的ID
let selectIdArr = ref<Records[]>([]);
//收集用户信息的响应式数据
let userParams = reactive({
  id: '',
  createTime: '',
  updateTime: '',
  createUser: '',
  updateUser: '',
  name: '',
  nickName: '',
  sex: '1',
  age: '',
  email: '',
  phone: '',
  birthday: '',
  address: '',
  avatar: '',
  description: '',
  username: '',
  password: '',
  userRoleList: []
});

const handleCheckAllChange = (val: boolean) => {
  //val:true(全选)|false(没有全选)
  userRole.value = val ? allRole.value : [];
  //不确定的样式(确定样式)
  isIndeterminate.value = false
}

//顶部全部的复选框的change事件
const handleCheckedCitiesChange = (value: string[]) => {
  //顶部复选框的勾选数据
  //代表:勾选上的项目个数与全部的职位个数相等，顶部的复选框勾选上
  checkAll.value = value.length === allRole.value.length;
  //不确定的样式
  isIndeterminate.value = value.length !== allRole.value.length
}

//表单校验的规则对象
const rules = reactive<FormRules>({
  //用户名字
  username: [{required: true, trigger: 'blur', message: "请输入用户账号"}],
  //用户的密码
  password: [{required: true, trigger: 'blur', message: "请输入密码"}],
})


onMounted(() => {
  getHasUser()
})

const getHasUser = async () => {
  const data = {
    pageNum: pageNum.value,
    pageSize: pageSize.value
  }
  const result: ApiResponse<Page<Records>> = await searchByCondition(data)
  if (result.code === 1000_0000) {
    totalRow.value = result.data.totalRow
    records.value = result.data.records
    avatar.value = result.data.records.map(item => item.avatar)
  }
}

// 搜索
const searchForm = async () => {
  const data = {
    name: searchDataForm.name,
    nickName: searchDataForm.nickName,
    phone: searchDataForm.phone,
    email: searchDataForm.email,
    pageNum: pageNum.value,
    pageSize: pageSize.value
  }
  const result = await searchByCondition(data)
  if (result.code === 1000_0000) {
    totalRow.value = result.data.totalRow
    records.value = result.data.records
    avatar.value = result.data.records.map(item => item.avatar)
  }
}

// 添加用户
const addUser = () => {
  drawer.value = true
  //清空数据
  Object.assign(userParams, {
    id: '',
    createTime: '',
    updateTime: '',
    createUser: '',
    updateUser: '',
    name: '',
    nickName: '',
    sex: '1',
    age: '',
    email: '',
    phone: '',
    birthday: '',
    address: '',
    avatar: '',
    description: '',
    username: '',
    password: '',
  });
  //清除上一次的错误的提示信息
  nextTick(() => {
    ruleFormRef.value?.clearValidate('username');
    ruleFormRef.value?.clearValidate('password');
  });
}

// 更新用户
const updateUser = (row: Records) => {
  drawer.value = true
  switch (row.sex) {
    case '男':
      row.sex = '1'
      break
    case '女':
      row.sex = '2'
      break
    default:
      row.sex = '3'
  }
  //存储收集已有的账号信息
  Object.assign(userParams, row);
  //清除上一次的错误的提示信息
  nextTick(() => {
    ruleFormRef.value?.clearValidate('username');
    ruleFormRef.value?.clearValidate('password');
  });
}

//保存按钮的回调
const save = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (!valid) {
      return
    }
    userParams.birthday = userParams.birthday !== '' ? formatDate(new Date(userParams.birthday)) : null
    // 保存按钮:添加新的用户|更新已有的用户账号信息
    const result = userParams.id ? await adminUpdateUserBaseInfo(userParams) : await adminAddUserBaseInfo(userParams)
    //添加或者更新成功
    if (result.code == 1000_0000) {
      //关闭抽屉
      drawer.value = false;
      //提示消息
      ElMessage({type: 'success', message: userParams.id ? '更新成功' : '添加成功'});
      //获取最新的全部账号的信息
      //浏览器自动刷新一次
      await getHasUser()
    }
  })
}

const setRole = async (row: Records) => {
  //存储已有的用户信息
  Object.assign(userParams, row);
  //获取全部的职位的数据与当前用户已有的职位的数据
  const result = await assignRoles(Number(row.id));
  if (result.code === 1000_0000) {
    let {userRoleList, roleList} = result.data;
    // 集合转成 UserRole 类型
    userRoleList = userRoleList.map((item: RoleData) => {
      return {
        id: item.roleId + '',
        roleName: item.roleName,
        roleCode: item.roleCode,
        roleDesc: item.roleDesc
      }
    })
    roleList = roleList.map((item: RoleData) => {
      return {
        id: item.id,
        roleName: item.roleName,
        roleCode: item.roleCode,
        roleDesc: item.roleDesc
      }
    })
    // 存储全部的职位
    allRole.value = roleList;
    // 存储当前用户已有的职位
    userRole.value = userRoleList;
    // 全选复选框
    checkAll.value = userRoleList.length === roleList.length;
    isIndeterminate.value = userRoleList.length !== roleList.length;
    // 抽屉显示出来
    drawer1.value = true;
  }
}

// 日期格式化
const formatDate = (date: Date) => {
  let year = date.getFullYear();
  let month = (date.getMonth() + 1).toString().padStart(2, '0');
  let day = date.getDate().toString().padStart(2, '0');
  let hours = date.getHours().toString().padStart(2, '0');
  let minutes = date.getMinutes().toString().padStart(2, '0');
  let seconds = date.getSeconds().toString().padStart(2, '0');
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

// 取消按钮的回调
const cancel = () => {
  //关闭抽屉
  drawer.value = false;
}

//确定按钮的回调(分配职位)
const confirmClick = async () => {
  //收集参数
  let data = {
    userId: (userParams.id),
    roleIds: userRole.value.map(item => {
      return (item.id as number)
    })
  }
  // 分配用户的职位
  let result: any = await setRoles(data);
  if (result.code === 1000_0000) {
    //提示信息
    ElMessage({type: 'success', message: '分配职务成功'});
    //获取更新完毕用户的信息,更新完毕留在当前页
    await getHasUser();
    //关闭抽屉
    drawer1.value = false;
  }
}

// 删除某一个用户
const deleteUser = async (userId: string) => {
  let result: any = await deleteById(userId);
  if (result.code === 1000_0000) {
    ElMessage({type: 'success', message: '删除成功'});
    getHasUser();
  }
}

//table复选框勾选的时候会触发的事件
const selectChange = (value: any) => {
  selectIdArr.value = value;
}

//批量删除按钮的回调
const deleteSelectUser = async () => {
  //整理批量删除的参数
  let idsList: any = selectIdArr.value.map(item => item.id);
  //批量删除的请求
  let result: any = await deleteByIds(idsList);
  if (result.code === 1000_0000) {
    ElMessage({type: 'success', message: '删除成功'});
    getHasUser();
  }
}

</script>

<style scoped lang="scss">
.top {
  margin-bottom: 2vh;

  .search-form {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .el-form-item {
      margin-bottom: 0;

      .el-input {
        width: 220px;
      }
    }
  }
}

.bottom {

  .bottom-table {
    margin: 2vh 0;

    .unfold-card {
      background-color: rgba(135 206 250 / .5);

      .unfold {
        width: 40%;
        display: flex;
        justify-content: space-between;

        p:first-child {
          margin-top: 0;
        }
      }
    }
  }
}

.dialog-add-or-update-form {
  width: 100%;
  display: flex;
  justify-content: space-between;

  .el-form-item {
    width: 45%;
  }
}

</style>

